<template>
  <div
    class="draggable-sider"
    :class="{ toggled, right: side === 'right' }"
    :style="{ minWidth: `${calcMinWidth}px`, maxWidth: `${maxWidth}px`, width: `${width}px` }"
    @mouseenter="onDraggableSiderMouseEnter"
    @mouseleave="onDraggableSiderMouseLeave"
  >
    <div class="draggable-sider__content" v-show="!toggled">
      <slot name="content"></slot>
    </div>
    <div
      id="dragHandler"
      v-show="!toggled"
      class="border-handler"
      :style="{ right: side === 'left' ? '-3px' : 'auto', left: side === 'right' ? '-3px' : 'auto' }"
      @mousedown.stop.prevent="onMouseDown"
    ></div>
    <!-- <sider-toggle v-if="needSiderToggle" :style="{ opacity: toggleInvisible ? 0 : 1 }" slot="toggle" class="tree-toggle" :side="side" :toggled="toggled" @click="onToggle" /> -->
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, defineEmits } from 'vue';

let currentX = 0;
let currentWidth = 0;

const props = defineProps<{
  minWidth: string | number;
  side: string;
  defaultToggled: boolean;
  autoHide: boolean;
  needSiderToggle: boolean;
}>();

const emit = defineEmits(['toggle']);

const toggled = ref(false);
const dragging = ref(false);
const calcMinWidth = ref(0);
const maxWidth = ref('none');
const originWidth = ref(0);
const width = ref(0);
const draggableSiderMouseOver = ref(false);

onMounted(() => {
  calcMinWidth.value = originWidth.value = width.value = typeof props.minWidth === 'string' ? parseInt(props.minWidth) : props.minWidth;
  maxWidth.value = `${Math.max(document.documentElement.clientWidth / 2, parseInt(props.minWidth as string))}`;
  document.documentElement.addEventListener('mousemove', onMouseMove);
  document.documentElement.addEventListener('mouseup', onMouseUp);
});

onBeforeUnmount(() => {
  document.documentElement.removeEventListener('mousemove', onMouseMove);
  document.documentElement.removeEventListener('mouseup', onMouseUp);
});

const onMouseDown = (e: MouseEvent) => {
  // console.log(`output->e`,e)
  dragging.value = true;
  currentX = e.clientX;
  currentWidth = parseInt(width.value as unknown as string);
};

const onMouseMove = (e: MouseEvent) => {
  // console.log(`output->e`,e)
  if (!dragging.value) return;
  const deltaX = e.clientX - currentX;
  let finalWidth = 0;
  if (props.side === 'left') {
    finalWidth = currentWidth + deltaX;
  } else if (props.side === 'right') {
    finalWidth = currentWidth - deltaX;
  }
  width.value = Math.max(finalWidth, parseInt(props.minWidth as string));
};

const onMouseUp = () => {
  if (dragging.value) {
    dragging.value = false;
    originWidth.value = width.value;
  }
};

const onDraggableSiderMouseEnter = () => {
  draggableSiderMouseOver.value = true;
};

const onDraggableSiderMouseLeave = () => {
  draggableSiderMouseOver.value = false;
};
</script>

<style lang="scss" scoped>
.draggable-sider {
  position: relative;
  height: 100%;
  box-shadow: 2px 4px 6px 0 #e4e4e4;
  transition: min-width 0.2s, max-width 0.2s;

  &__content {
    height: 100%;
    width: 100%;
    overflow-y: auto;
  }

  .border-handler {
    position: absolute;
    width: 6px;
    top: 0;
    bottom: 0;
    cursor: col-resize;
  }

  .tree-toggle {
    position: absolute;
    top: 50%;
    right: -20px;
    transform: translateY(-50px);
    z-index: 999;
    transition: opacity 0.3s;
  }

  &.right {
    box-shadow: -2px 4px 6px 0 #e4e4e4;
    .tree-toggle {
      left: -20px;
      right: auto;
    }
  }

  &.toggled {
    .tree-toggle {
      opacity: 1;
    }
  }
}
</style>
